#include "qqmusic.h"
#include "ui_qqmusic.h"
#include"volumetool.h"
#include<QDebug>
#include<QJsonArray>
#include<QMouseEvent>
#include<QGraphicsDropShadowEffect>
#include<QFileDialog>
#include<QDir>
#include<QSqlError>
#include<QSqlQuery>
#include<QMessageBox>
#include<QSystemTrayIcon>
#include<QMenu>


///没有歌词
QQMusic::QQMusic(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::QQMusic)
{
    ui->setupUi(this);
    InitUI();
    InitSqlite();
    InitMusicList();
    initPlayer();
    connectSignalsAndSlots();
}

QQMusic::~QQMusic()
{
    delete ui;
}

void QQMusic::InitUI()
{
    //设置无标题栏
    this->setWindowFlag(Qt::WindowType::FramelessWindowHint);
    //设置窗口透明
    this->setAttribute(Qt::WA_TranslucentBackground);
    //设置窗口图标
    setWindowIcon(QIcon(":/image/tubiao.png"));
    //添加托盘
    QSystemTrayIcon* trayIcon=new QSystemTrayIcon(this);
    trayIcon->setIcon(QIcon(":/image/tubiao.png"));
    //添加托盘菜单
    QMenu* trayMenu=new QMenu(this);
    trayMenu->addAction("显示",this,&QWidget::showNormal);
    trayMenu->addSeparator();
    trayMenu->addAction("退出",this,&QQMusic::quitQQMusic);

    trayIcon->setContextMenu(trayMenu);
    trayIcon->show();

    //设置最大化禁止
    ui->max->setEnabled(false);
    //设置窗口阴影效果
    QGraphicsDropShadowEffect* shadowEffect=new QGraphicsDropShadowEffect(this);
    shadowEffect->setOffset(0,0);// 设置阴影偏移
    shadowEffect->setColor("#000000");
    shadowEffect->setBlurRadius(5);////////////////////////////////////////////////////////////////////////要修改动画有冲突
    this->setGraphicsEffect(shadowEffect);

    //设置BodyLeft中6个myForm的信息
    ui->rec->setIconAndText(":/image/rec.png","推荐",0);
    ui->radio->setIconAndText(":/image/radio.png","电台",1);
    ui->music->setIconAndText(":/image/music.png","音乐馆",2);
    ui->like->setIconAndText(":/image/like.png","我喜欢",3);
    ui->local->setIconAndText(":/image/local.png","本地下载",4);
    ui->recent->setIconAndText(":/image/recent.png","最近播放",5);

    //默认本地下载显示动画效果
    ui->local->showAnimal(true);
    ui->stackedWidget->setCurrentIndex(4);
    currentPage=ui->localPage;

    //randomPicture();
    srand(time(NULL));
    ui->recMusicBox->initRecBoxUi(randomPicture(),1);
    ui->supplyMusicBox->initRecBoxUi(randomPicture(),2);

    ui->likePage->setCommonPageUi("我喜欢",":/image/ilikebg.png");

    ui->localPage->setCommonPageUi("本地下载",":/image/localbg.png");

    ui->recentPage->setCommonPageUi("最近播放",":/image/recentbg.png");

    ui->play->setIcon(QIcon(":/image/pause.png"));
    ui->playMode->setIcon(QIcon(":/image/random.png"));
    volume=new VolumeTool(this);

    lrcPage=new LrcPage(this);
    lrcPage->hide();

    lrcAnimation=new QPropertyAnimation(lrcPage,"geometry",this);
    lrcAnimation->setDuration(500);
    lrcAnimation->setStartValue(QRect(9,9+lrcPage->height(),lrcPage->width(),lrcPage->height()));
    lrcAnimation->setEndValue(QRect(9,9,lrcPage->width(),lrcPage->height()));

}

void QQMusic::InitSqlite()
{
    sqlite=QSqlDatabase::addDatabase("QSQLITE");
    sqlite.setDatabaseName("QQMusic.db");
    if(!sqlite.open())
    {
        qDebug()<<"连接数据库失败"<<sqlite.lastError().text();
        return;
    }
    qDebug()<<"连接数据库成功";

    QString sql=("create table if not exists musicInfo(\
                 id integer primary key autoincrement,\
                 musicId varchar(200) unique,\
                 musicName varchar(50),\
                 musicSinger varchar(50),\
                 albumName varchar(50),\
                 duration bigint,\
                 musicUrl varchar(256),\
                 isLike integer,\
                 isHistory integer)"
            );
    QSqlQuery query;
    if(!query.exec(sql))
    {
        qDebug()<<"创建表失败"<<query.lastError().text();
        return;
    }
    qDebug()<<"创建表成功";
}

void QQMusic::InitMusicList()
{
    musicList.readFromDB();
    ui->likePage->setMuiscPageType(PageType::LIKE_PAGE);
    ui->likePage->reFresh(musicList);

    ui->localPage->setMuiscPageType(PageType::LOCAL_PAGE);
    ui->localPage->reFresh(musicList);

    ui->recentPage->setMuiscPageType(PageType::RECENT_PAGE);
    ui->recentPage->reFresh(musicList);
}

void QQMusic::initPlayer()
{
    player=new QMediaPlayer(this);
    playList=new QMediaPlaylist(this);

    //设置播放模式
    playList->setPlaybackMode(QMediaPlaylist::Random);
    ui->playMode->setToolTip("随机播放");
    //将播放列表设置给播放器
    player->setPlaylist(playList);
    //设置音量
    player->setVolume(20);

    connect(ui->play,&QPushButton::clicked,this,&QQMusic::onPlayClicked);
    connect(player,&QMediaPlayer::stateChanged,this,&QQMusic::onStateChanged);

    connect(ui->playUp,&QPushButton::clicked,this,&QQMusic::onPlayUp);
    connect(ui->playDown,&QPushButton::clicked,this,&QQMusic::onPlayDown);

    connect(ui->playMode,&QPushButton::clicked,this,&QQMusic::onPlaybackModeClicked);
    connect(playList,&QMediaPlaylist::playbackModeChanged,this,&QQMusic::onPlaybackModeChanged);
    connect(playList,&QMediaPlaylist::currentIndexChanged,this,&QQMusic::onCurrentIndexChanged);

    connect(player,&QMediaPlayer::durationChanged,this,&QQMusic::onDurationChanged);
    connect(player,&QMediaPlayer::positionChanged,this,&QQMusic::onPositionChanged);

    connect(player,&QMediaPlayer::metaDataAvailableChanged,this,&QQMusic::onMetaDataAvailableChangedChanged);
}

void QQMusic::connectSignalsAndSlots()
{
    connect(ui->rec,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->radio,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->music,&myForm::myClick,this,&QQMusic::onMyFormClick);

    connect(ui->like,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->local,&myForm::myClick,this,&QQMusic::onMyFormClick);
    connect(ui->recent,&myForm::myClick,this,&QQMusic::onMyFormClick);

    connect(ui->likePage,&CommonPage::updataLikeMusic,this,&QQMusic::onupdataLikeMusic);
    connect(ui->localPage,&CommonPage::updataLikeMusic,this,&QQMusic::onupdataLikeMusic);
    connect(ui->recentPage,&CommonPage::updataLikeMusic,this,&QQMusic::onupdataLikeMusic);

    connect(ui->likePage,&CommonPage::playAll,this,&QQMusic::onPlayAll);
    connect(ui->localPage,&CommonPage::playAll,this,&QQMusic::onPlayAll);
    connect(ui->recentPage,&CommonPage::playAll,this,&QQMusic::onPlayAll);

    connect(ui->likePage,&CommonPage::playMusicByIndex,this,&QQMusic::onPlayMusicByIndex);
    connect(ui->localPage,&CommonPage::playMusicByIndex,this,&QQMusic::onPlayMusicByIndex);
    connect(ui->recentPage,&CommonPage::playMusicByIndex,this,&QQMusic::onPlayMusicByIndex);

    connect(volume,&VolumeTool::setSilence,this,&QQMusic::onSetMusicSilence);
    connect(volume,&VolumeTool::setMusicVolume,this,&QQMusic::onSetMusicVolume);

    connect(ui->processBar,&MusicSlider::setMusicSliderPosition,this,&QQMusic::onMusicSliderChanged);
    connect(ui->lrcWord,&QPushButton::clicked,this,&QQMusic::onLrcWordClicked);
}

/********************************************
 *
 * arg(i, 3, 10, QCchar('0'))
 * i：要放⼊%1位置的数据
 * 3: 三位数
 * 10：表⽰⼗进制数
 * QChar('0')：数字不够三位，前⾯⽤字符'0'填充
 *
 * ******************************************/

QJsonArray QQMusic::randomPicture()
{
    QVector<QString> vecImageName;
    vecImageName<<"001.png"<<"002.png"<<"003.png"<<"004.png"<<"005.png"<<"006.png"
                <<"007.png"<<"008.png"<<"009.png"<<"010.png"<<"011.png"<<"012.png"
                <<"013.png"<<"014.png"<<"015.png"<<"016.png"<<"017.png"<<"018.png"
                <<"019.png"<<"020.png"<<"021.png"<<"022.png"<<"023.png"<<"024.png"
                <<"025.png"<<"026.png"<<"027.png"<<"028.png"<<"029.png"<<"030.png"
                <<"031.png"<<"032.png"<<"033.png"<<"034.png"<<"035.png"<<"036.png"
                <<"037.png"<<"038.png"<<"039.png";
    std::random_shuffle(vecImageName.begin(),vecImageName.end());

    QJsonArray objArray;
    for(int i=0;i<vecImageName.size();i++)
    {
        QJsonObject obj;
        obj.insert("path",":/image/rec/"+vecImageName[i]);

        QString strText=QString("推荐-%1").arg(++i,3,10,QChar('0'));
        obj.insert("text",strText);
        objArray.append(obj);
    }
    return objArray;
}

void QQMusic::playAllOfCommonPage(CommonPage *page, int index)
{
    currentPage=page;
    updateMyformAnimal();
    playList->clear();//清空一下播放列表
    page->addMusicToPlayer(musicList,playList);//加载当前页面歌曲
    playList->setCurrentIndex(index);//设置播放索引
    player->play();
}

void QQMusic::on_exit_clicked()
{
    hide();
}

void QQMusic::quitQQMusic()
{
    musicList.writeToDB();
    sqlite.close();
    this->close();
}

void QQMusic::onMyFormClick(int pageId)
{
    QList<myForm*> myFormList=this->findChildren<myForm*>();
    for(auto&myForm:myFormList)
    {
        if(myForm->getPageId()!=pageId)
        {
            myForm->clearBackground();
        }
    }
    qDebug()<<"更换界面: "<<pageId;
    ui->stackedWidget->setCurrentIndex(pageId);
    isDrag=false;
}


/*************************************************************
 *
 * event->globalPos()：⿏标按下事件发⽣时，光标相对于屏幕左上⻆位置
 * frameGeometry().topLeft(): ⿏标按下事件发⽣时，窗⼝左上⻆位置
 * geometry(): 不包括边框及顶部标题区的范围
 * frameGeometry(): 包括边框及顶部标题区的范围
 * event->globalPos() - frameGeometry().topLeft() 即为：⿏标按下时，窗⼝左上⻆和光标之间的距离差
 * 想要窗⼝⿏标按下时窗⼝移动，只需要在mouseMoveEvent中，让光标和窗⼝左上⻆保持相同的位置差获取⿏标相对于屏幕左上⻆的全局坐标
 *
 * ***********************************************************/

void QQMusic::mousePressEvent(QMouseEvent *event)
{
    (void)event;
    if(event->button()==Qt::LeftButton)
    {
        isDrag=true;
        dragPosition=event->globalPos()-this->frameGeometry().topLeft();
        return;
    }
    QWidget::mousePressEvent(event);
}

void QQMusic::mouseMoveEvent(QMouseEvent *event)
{
    (void)event;
    if(event->buttons()==Qt::LeftButton&&isDrag)
    {
        move(event->globalPos()-dragPosition);
        return;
    }
    QWidget::mouseMoveEvent(event);
}



void QQMusic::on_volume_clicked()
{
    //获取ui->volume的左上角坐标，并转换为基类的全局坐标
    QPoint point=ui->volume->mapToGlobal(QPoint(0,0));//???
    QPoint volumeLeftTop=point-QPoint(volume->width()/2,volume->height());

    volumeLeftTop.setX(volumeLeftTop.x()+15);
    volumeLeftTop.setY(volumeLeftTop.y()+30);
    volume->move(volumeLeftTop);
    volume->show();
}

/**********************************
 *
 * 过滤器
 * 1.通过文件后缀fileDialog.setNameFilter ---->只能过滤一种
 *   通过文件后缀fileDialog.setNameFilters ---->过滤多种
 * 2.通过文件的MIME类型过滤
 *
 * **********************************/

void QQMusic::on_addLocal_clicked()
{
    //创建一个对话框
    QFileDialog fileDialog(this);
    fileDialog.setWindowTitle("添加本地音乐");
    //创建一个打开格式的文件对话框
    fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
    //设置对话框模式
    fileDialog.setFileMode(QFileDialog::ExistingFiles);
    //设置对话框的MIME过滤器
    QStringList mimeList;
    mimeList<<"application/octet-stream";
    fileDialog.setMimeTypeFilters(mimeList);

    //fileDialog.setNameFilter("代码文件(*.h *.c *.cpp)");

    //设置打开路径
    QDir dir(QDir::currentPath());
    dir.cdUp();
    QString url=dir.path()+"/QQMusic/Music/";
    fileDialog.setDirectory(url);


    if(fileDialog.exec()==QDialog::Accepted)//模态对话框
    {
        QList<QUrl> fileUrls=fileDialog.selectedUrls();//选中的所有文件的url路径
        musicList.addMusicByUrl(fileUrls);

        ui->stackedWidget->setCurrentIndex(4);
        ui->localPage->reFresh(musicList);

    }
    ui->localPage->addMusicToPlayer(musicList,playList);
}

void QQMusic::onupdataLikeMusic(bool isLike, const QString &musicId)
{
    auto it=musicList.findMusicById(musicId);
    if(it!=musicList.end())
    {
        it->setIsLike(isLike);
    }
    ui->likePage->reFresh(musicList);
    ui->localPage->reFresh(musicList);
    ui->recentPage->reFresh(musicList);
}

void QQMusic::onPlayClicked()
{
    if(player->state()==QMediaPlayer::PlayingState)
    {
        player->pause();
    }
    else if(player->state()==QMediaPlayer::PausedState)
    {
        player->play();
    }
    else if(player->state()==QMediaPlayer::StoppedState)
    {
        player->play();
    }
    else
        qDebug()<<"播放出现故障，请抓紧维修";
}

void QQMusic::onStateChanged()
{
    if(player->state()==QMediaPlayer::PlayingState)
    {
        ui->play->setIcon(QIcon(":/image/play.png"));

    }
    else
    {
        ui->play->setIcon(QIcon(":/image/pause.png"));
    }
}

void QQMusic::onPlaybackModeClicked()
{
    if(playList->playbackMode()==QMediaPlaylist::Random)
    {
        playList->setPlaybackMode(QMediaPlaylist::Loop);
        ui->playMode->setToolTip("列表循环");
    }
    else if(playList->playbackMode()==QMediaPlaylist::Loop)
    {
        playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
        ui->playMode->setToolTip("单曲循环");
    }
    else if(playList->playbackMode()==QMediaPlaylist::CurrentItemInLoop)
    {
        playList->setPlaybackMode(QMediaPlaylist::Random);
        ui->playMode->setToolTip("随机播放");
    }
    else
        qDebug()<<"暂未支持,敬请期待";
}

void QQMusic::onPlayUp()
{
    playList->previous();
}

void QQMusic::onPlayDown()
{
    playList->next();
}

void QQMusic::onPlaybackModeChanged(QMediaPlaylist::PlaybackMode playbackMode)
{
    if(playbackMode==QMediaPlaylist::Random)
    {
        ui->playMode->setIcon(QIcon(":/image/random.png"));
    }
    else if(playbackMode==QMediaPlaylist::Loop)
    {
        ui->playMode->setIcon(QIcon(":/image/loop.png"));
    }
    else if(playbackMode==QMediaPlaylist::CurrentItemInLoop)
    {
        ui->playMode->setIcon(QIcon(":/image/CurrentItemInLoop.png"));
    }
    else
        qDebug()<<"暂未支持,敬请期待";
}

void QQMusic::onPlayAll(PageType pageType)
{
    CommonPage* page=nullptr;
    switch (pageType)
    {
    case LIKE_PAGE:
        page=ui->likePage;
        break;
    case LOCAL_PAGE:
        page=ui->localPage;
        break;
    case RECENT_PAGE:
        page=ui->recentPage;
        break;
    default:
        qDebug()<<"暂未支持，敬请期待";
    }
    playAllOfCommonPage(page,0);
}

void QQMusic::onPlayMusicByIndex(CommonPage *page, int index)
{
    playAllOfCommonPage(page,index);
}

void QQMusic::onCurrentIndexChanged(int index)
{
    currentPlayMusicIndex=index;
    QString musicId=currentPage->getMusicIdByIndex(index);
    auto it=musicList.findMusicById(musicId);
    if(it!=musicList.end())
    {
        it->setIsHistory(true);
    }
    ui->recentPage->reFresh(musicList);
}

void QQMusic::onSetMusicSilence(bool isMuted)
{
    player->setMuted(isMuted);
}

void QQMusic::onSetMusicVolume(int volume)
{
    player->setVolume(volume);
}

void QQMusic::onDurationChanged(qint64 duration)
{
    totalDuration=duration;
    ui->totalTime->setText(QString("%1:%2").arg(duration/1000/60,2,10,QChar('0'))
                           .arg(duration/1000%60,2,10,QChar('0')));
}

void QQMusic::onPositionChanged(qint64 position)
{
    ui->currentTime->setText(QString("%1:%2").arg(position/1000/60,2,10,QChar('0'))
                             .arg(position/1000%60,2,10,QChar('0')));
    ui->processBar->setStep((float)position/(float)totalDuration);
    if(playList->currentIndex()>=0)
    {
        lrcPage->ShowLineLrcWord(position);
    }
}

void QQMusic::onMusicSliderChanged(float ratio)
{
    qint64 currentTime=(qint64)(ratio*totalDuration);
    ui->currentTime->setText(QString("%1:%2").arg(currentTime/1000/60,2,10,QChar('0'))
                             .arg(currentTime/1000%60,2,10,QChar('0')));
    player->setPosition(currentTime);
}

void QQMusic::onMetaDataAvailableChangedChanged(bool available)
{
    (void)available;
    qDebug()<<"歌曲更换";
    QString musicName=player->metaData("Title").toString();
    QString singer=player->metaData("Author").toStringList().join(",");
    if(musicName.isEmpty())
    {
        auto currentMusic=musicList.findMusicById(currentPage->getMusicIdByIndex(currentPlayMusicIndex));
        if(currentMusic!=musicList.end())
        {
            musicName=currentMusic->getMusicName();
            singer=currentMusic->getMusicSinger();
        }
    }
    ui->musicName->setText(musicName);
    ui->musicSinger->setText(singer);

    QVariant coverImage=player->metaData("ThumbnailImage");
    if(coverImage.isValid())
    {
        QImage image=coverImage.value<QImage>();
        ui->musicCover->setPixmap(QPixmap::fromImage(image));
        currentPage->setImageLabel(QPixmap::fromImage(image));
    }
    else
    {
        QString image=":/image/rec/038.png";
        ui->musicCover->setPixmap(image);
        currentPage->setImageLabel(image);
    }
    ui->musicCover->setScaledContents(true);

    QString musicIndex=currentPage->getMusicIdByIndex(currentPlayMusicIndex);
    auto it=musicList.findMusicById(musicIndex);
    if(it!=musicList.end())
    {
        lrcPage->parseLrc(it->getLrcFilePath());//getLrcFilePath是只读函数不可以修改所以parseLrc不能&
        lrcPage->ShowLrcMusicName(it->getMusicName());
        lrcPage->ShowLrcMusicSinger(it->getMusicSinger());
    }
}

void QQMusic::onLrcWordClicked()
{
    lrcPage->show();
    lrcAnimation->start();
}



void QQMusic::on_min_clicked()
{
    showMinimized();
}

void QQMusic::on_skin_clicked()
{
    QMessageBox::information(this,"温馨提示","未支持，请期待！");
}

void QQMusic::updateMyformAnimal()
{
    int index=ui->stackedWidget->indexOf(currentPage);
    if(index==-1)
    {
        qDebug()<<"无此页面";
        return;
    }
    QList<myForm*> myForms=this->findChildren<myForm*>();
    for(auto myForm:myForms)
    {
        if(myForm->getPageId()==index)
        {
            myForm->showAnimal(true);
        }
        else
        {
            myForm->showAnimal(false);
        }
    }
}
